/*
 * EditDependent.java
 * This class enables the user to edit a dependent individually from an
 * associated family.
 */

package gui;
import db.DBManager;
import struct.*;
import javax.swing.*;
import javax.swing.table.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.text.SimpleDateFormat;

/**
 *
 * @author Sarah Wegner
 */
public class EditDependent extends javax.swing.JFrame {

    /*Variables*/
    Dependent individual;//original info from database
    String[] originalIndividualInfoArray;//list of all orig. individual attribs.
    String[] depKey = new String[3];

    ArrayList<String> ministryNames;//MinistryName drop-down

    Object[] editRecord;
    //ArrayList<Adult> adult;//list of all orig. adults and their attributes
    int depSize;

    ArrayList<Interest> interest;//list of orig. ministry interests
    int interestSize;
    String[] originalInterest;

    ArrayList<History> history;//list of orig. ministry histories
    int historySize;
    String[] originalHistory;

    //cannot add dependent
    //cannot delete dependent
    ArrayList<Integer> depUpdatedList = new ArrayList();//keep track of adults updated

    ArrayList<Integer> interestAddedList = new ArrayList();//keep track of interests added
    ArrayList<Integer> interestDeletedList = new ArrayList();//keep track of interests deleted
    ArrayList<Integer> interestUpdatedList = new ArrayList();//keep track of interests updated

    ArrayList<Integer> historyAddedList = new ArrayList();//keep track of History added
    ArrayList<Integer> historyDeletedList = new ArrayList();//keep track of History deleted
    ArrayList<Integer> historyUpdatedList = new ArrayList();//keep track of History updated


    /** Creates new form EditAdult */
    public EditDependent(String[] depArray) {
        initComponents();
        initFields(depArray);
        initArrayLists();//initialize add/update/delete arraylists to keep track of transactions
    }//EditDependent()

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        btCancel = new javax.swing.JButton();
        tabbedPane = new javax.swing.JTabbedPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        jDependentTable = new javax.swing.JTable();
        jScrollPane2 = new javax.swing.JScrollPane();
        jMinistryInterestTable = new javax.swing.JTable();
        jScrollPane3 = new javax.swing.JScrollPane();
        jMinistryHistoryTable = new javax.swing.JTable();
        btSave = new javax.swing.JButton();
        btRemoveRow = new javax.swing.JButton();
        jSeparator2 = new javax.swing.JSeparator();
        btAddRow = new javax.swing.JButton();
        lblAddNewHousehold = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        btCancel.setText("Cancel");
        btCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btCancelActionPerformed(evt);
            }
        });

        jDependentTable.setBackground(new java.awt.Color(230, 230, 255));
        jDependentTable.setModel(dependentTableModel);
        jDependentTable.setName("editDependentIndividual"); // NOI18N
        jScrollPane1.setViewportView(jDependentTable);

        tabbedPane.addTab("Dependent Information", jScrollPane1);

        jMinistryInterestTable.setBackground(new java.awt.Color(230, 230, 255));
        jMinistryInterestTable.setModel(ministryInterestTableModel);
        jMinistryInterestTable.setName("editDependentInterest"); // NOI18N
        jScrollPane2.setViewportView(jMinistryInterestTable);

        tabbedPane.addTab("Ministry Interest", jScrollPane2);

        jMinistryHistoryTable.setBackground(new java.awt.Color(230, 230, 255));
        jMinistryHistoryTable.setModel(ministryHistoryTableModel);
        jMinistryHistoryTable.setName("editDependentHistory"); // NOI18N
        jScrollPane3.setViewportView(jMinistryHistoryTable);

        tabbedPane.addTab("Ministry History", jScrollPane3);

        btSave.setText("Save");
        btSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btSaveActionPerformed(evt);
            }
        });

        btRemoveRow.setText("Delete Row");
        btRemoveRow.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btRemoveRowActionPerformed(evt);
            }
        });

        jSeparator2.setForeground(new java.awt.Color(0, 153, 0));

        btAddRow.setText("Add Row");
        btAddRow.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btAddRowActionPerformed(evt);
            }
        });

        lblAddNewHousehold.setFont(new java.awt.Font("Tahoma", 0, 14));
        lblAddNewHousehold.setText("Edit Dependent");

        jLabel1.setFont(new java.awt.Font("Tahoma", 2, 10));
        jLabel1.setText("Edit dependent information by editing from the family record.");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lblAddNewHousehold)
                    .addComponent(jLabel1)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(tabbedPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 1062, Short.MAX_VALUE)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(btRemoveRow)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(btAddRow)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(btCancel)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(btSave, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap(27, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblAddNewHousehold)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 258, Short.MAX_VALUE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btSave)
                    .addComponent(btCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btAddRow)
                    .addComponent(btRemoveRow))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * Cancels any edited information and closes the window.
     * @param evt
     */
    private void btCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btCancelActionPerformed
        //Cancel Save and Close Window
        int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                "you would like to close "+ "\n"+ "this window without saving?",
                "Cancel", JOptionPane.YES_NO_OPTION);
        if (answer == JOptionPane.YES_OPTION) {
            // User clicked YES.
            this.dispose();
        } //else if (answer == JOptionPane.NO_OPTION)
         // User clicked NO. Do nothing.
}//GEN-LAST:event_btCancelActionPerformed

    /**
     * Validates all the save information before a save to the database.
     * @param evt
     */
    private void btSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btSaveActionPerformed

        //Stop Cell editing on all Tabs
        stopCellEditing(jDependentTable);
        stopCellEditing(jMinistryInterestTable);
        stopCellEditing(jMinistryHistoryTable);

        //1. Check for required Fields in all Tabs
        String requiredFields = verifyRequiredFields();
        //2. Check for duplicate rows in all Tabs
        String dupTabs = verifyDuplicateRows();
        //3. Check for proper date format in all Tabs
        String dateFields = verifyDateFields();
        //4. Check for proper phone format in all Tabs
        String phoneFields = verifyPhoneFields();

        if(!requiredFields.equals("")){
            JOptionPane.showMessageDialog(null, "Please complete the "
                    + "required fields for the following tabs: "
                    + "\n" + requiredFields + "\n\n" +
                    "Note: If a row is empty and is not needed in a particular table, delete"
                    + " the row, then click the 'Save' button. All required"
                    + " fields are marked with a '*'.",
                    "Save Error", JOptionPane.WARNING_MESSAGE);
        }//if
        else if(!dupTabs.equals(""))
        {
            JOptionPane.showMessageDialog(null, "The following tabs"
                    + " have duplicate rows: "
                    + "\n" + dupTabs + "\n" + "Please remove the duplicate rows before continuing.",
                    "Save Error", JOptionPane.WARNING_MESSAGE);
        }//if
        else if(!dateFields.equals(""))
        {
            JOptionPane.showMessageDialog(null, "The Tabs listed below have dates "
                    + "in incorrect format. Please use MM/DD/YYYY."
                    + "\n" + dateFields, "Save Error", JOptionPane.WARNING_MESSAGE);
        }//if
        else if(!phoneFields.equals("")){
            JOptionPane.showMessageDialog(null, "The Tabs listed below have phone numbers "
                    + "in incorrect format. Please use (XXX)XXX-XXXX." + "\n" +"Ex: (920)555-5491"
                    + "\n" + phoneFields, "Save Error", JOptionPane.WARNING_MESSAGE);
        }//if
        else{
            save();
        }//else
}//GEN-LAST:event_btSaveActionPerformed

    private void btRemoveRowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btRemoveRowActionPerformed
         //Remove row in table if the user does not find it necessary
        //index of deleted col
        int deletedCol;
        //get index of selected tab
        int tabIndex = tabbedPane.getSelectedIndex();
        if(tabIndex == 0){
            JOptionPane.showMessageDialog(null,"You must have an adult record.",
                    "Delete",JOptionPane.WARNING_MESSAGE);
        }//tabIndex = 0
        ////////////////////////////////////////////////////////////////////////
        else if(tabIndex == 1){
            int interestRowCount = jMinistryInterestTable.getRowCount();
            //confirm delete of row.
            if(interestRowCount > 0){
                int row = jMinistryInterestTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        /*disable selected row & color different*/
                        deletedCol = jMinistryInterestTable.getColumnCount()-1;
                        jMinistryInterestTable.setValueAt(true, row, deletedCol);
                        jMinistryInterestTable.changeSelection(row, deletedCol, false, false);
                        jMinistryInterestTable.requestFocus();

                        /*delete from update and add lists*/
                        if(interestUpdatedList.contains((Integer)row)){
                            interestUpdatedList.remove((Integer)row);
                            /*add to delete row index*/
                            interestDeletedList.add((Integer)row);
                        }//if
                        if(interestAddedList.contains((Integer)row)){
                            interestAddedList.remove((Integer)row);
                        }//if
                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to remove first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "Please select a row to remove first.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 1
        ////////////////////////////////////////////////////////////////////////
        else if(tabIndex == 2){
            int historyRowCount = jMinistryHistoryTable.getRowCount();
            //confirm delete of row.
            if(historyRowCount > 0){
                int row = jMinistryHistoryTable.getSelectedRow();
                if(row >= 0){
                    int answer = JOptionPane.showConfirmDialog(null, "Are you sure "+
                        "you would like to delete this record?",
                        "Delete", JOptionPane.YES_NO_OPTION);
                    if (answer == JOptionPane.YES_OPTION) {
                        /*disable selected row & color different*/
                        deletedCol = jMinistryHistoryTable.getColumnCount()-1;
                        jMinistryHistoryTable.setValueAt(true, row, deletedCol);
                        jMinistryHistoryTable.changeSelection(row, deletedCol, false, false);
                        jMinistryHistoryTable.requestFocus();

                        /*delete from update and add lists*/
                        if(historyUpdatedList.contains((Integer)row)){
                            historyUpdatedList.remove((Integer)row);

                            /*add to delete row index*/
                            historyDeletedList.add((Integer)row);
                        }//if
                        if(historyAddedList.contains((Integer)row)){
                            historyAddedList.remove((Integer)row);
                        }//if

                    }//else-do nothing
                }//if
                else{
                    JOptionPane.showMessageDialog(null,
                            "Please select a row to remove first.", "Delete",
                            JOptionPane.WARNING_MESSAGE);
                }//row not selected
            }//if rows > 0
            else{
                JOptionPane.showMessageDialog(null,
                    "Please select a row to remove first.", "Delete",
                    JOptionPane.WARNING_MESSAGE);
            }//else
        }//tabIndex = 2
}//GEN-LAST:event_btRemoveRowActionPerformed

    private void btAddRowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btAddRowActionPerformed
        //get index of selected tab
        int tabIndex = tabbedPane.getSelectedIndex();
        //Only 2 adults are allowed per family
        //Disable add row button if adults > 2
        if(tabIndex == 0){
            JOptionPane.showMessageDialog(null,
                "You are not able to add adults to this individuals record.", "Add Adult",
                JOptionPane.WARNING_MESSAGE);
        }//tabIndex = 0
        else if(tabIndex == 1){
            //the index of the new row will be the same as the orig. row count

            interestAddedList.add((Integer)ministryInterestTableModel.getRowCount());
            ministryInterestTableModel.addRow(new Object[] {"","",false});
//            jMinistryInterestTable.changeSelection(ministryInterestTableModel.getRowCount()-1,0,false,false);
//            jMinistryInterestTable.requestFocus();
        }//tabIndex = 1
        else if(tabIndex == 2){
            //the index of the new row will be the same as the orig. row count
            historyAddedList.add((Integer)ministryHistoryTableModel.getRowCount());
            ministryHistoryTableModel.addRow(new Object[] {"","","",false});
        }//tabIndex = 2
}//GEN-LAST:event_btAddRowActionPerformed


    /**
     * Saves edited information to database
     */
    private void save(){
        try{
            DBManager dbManager = new DBManager();
            ///////////////////////////////////////////////////////////////////
            //1. Delete Objects from Database
            ///////////////////////////////////////////////////////////////////
            int interestDeletedSize = getSize(interestDeletedList);
            int historyDeletedSize = getSize(historyDeletedList);

            //Delete Dependent
            //Cannot delete the Dependent

            //Delete Interest
            boolean deleteInterest;
            for(int i = 0; i < interestDeletedSize; i++){
                deleteInterest = false;
                int index = interestDeletedList.get(i);
                String[] interestKey = interest.get(index).getKey();
                deleteInterest = dbManager.deleteRecord("dinterest", interestKey, depKey);
                if(!deleteInterest){
                    deleteSaveError("interest");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for
            //Delete History
            boolean deleteHistory;
            for(int i = 0; i < historyDeletedSize; i++){
                deleteHistory = false;
                int index = historyDeletedList.get(i);
                String[] historyKey = history.get(index).getKey();
                deleteHistory = dbManager.deleteRecord("dhistory", historyKey, depKey);
                if(!deleteHistory){
                    deleteSaveError("history");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            ////////////////////////////////////////////////////////////////////
            //2. Add components to database
            ////////////////////////////////////////////////////////////////////
            int interestAddSize = getSize(interestAddedList);
            int historyAddSize = getSize(historyAddedList);

            //Add Dependents
            //can't add deps to this record.

            //Add Interest
            boolean addInterests;
            for(int i = 0; i < interestAddSize; i++){
                addInterests = false;
                int index = interestAddedList.get(i);
                Object[] interestAttribs = new Object[ministryInterestTableModel.getColumnCount()-1];
                for(int j = 0; j < ministryInterestTableModel.getColumnCount()-1; j++){
                    interestAttribs[j] = ministryInterestTableModel.getValueAt(index, j);
                }//for
                Interest interestObj = new Interest((String)interestAttribs[0],
                                           (String)interestAttribs[1]);
                addInterests = dbManager.addRecord("dinterest", interestObj, depKey);
                if(!addInterests){
                    addSaveError("a ministry interest");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Add History
            boolean addHistories;
            for(int i = 0; i < historyAddSize; i++){
                addHistories = false;
                int index = historyAddedList.get(i);
                Object[] historyAttribs = new Object[ministryHistoryTableModel.getColumnCount()-1];
                for(int j = 0; j < ministryHistoryTableModel.getColumnCount()-1; j++){
                    historyAttribs[j] = ministryHistoryTableModel.getValueAt(index, j);
                }
                History historyObj = new History((String)historyAttribs[0],
                                                 (String)historyAttribs[1],
                                                 (String)historyAttribs[2]);
                addHistories = dbManager.addRecord("dhistory", historyObj, depKey);
                if(!addHistories){
                    addSaveError("a ministry history");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            ////////////////////////////////////////////////////////////////////
            //3. Update Components
            ////////////////////////////////////////////////////////////////////
            int depUpdateSize = getSize(depUpdatedList);
            int interestUpdateSize = getSize(interestUpdatedList);
            int historyUpdateSize = getSize(historyUpdatedList);

            //Update Dependents
            boolean updateDeps;
            for(int i = 0; i < depUpdateSize; i++){
                updateDeps = false;
                int index = depUpdatedList.get(i);
                String[] depAttribs = new String[dependentTableModel.getColumnCount()-1];
                for(int j = 0; j < dependentTableModel.getColumnCount()-1; j++){
                    depAttribs[j] = (String)dependentTableModel.getValueAt(index, j);
                }
                Dependent depObj = new Dependent(depAttribs[0],
                                                depAttribs[1],
                                                depAttribs[2],
                                                depAttribs[3],depAttribs[4],
                                                depAttribs[5],depAttribs[6]);
                //Use the original individual info
                //in the depUpdatedList
                updateDeps = dbManager.updateRecord("",individual,depObj, depKey);
                if(!updateDeps){
                    updateSaveError("a dependent");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Update Interests
            boolean updateInterests;
            for(int i = 0; i < interestUpdateSize; i++){
                updateInterests = false;
                int index = interestUpdatedList.get(i);
                Object[] interestAttribs = new Object[ministryInterestTableModel.getColumnCount()-1];
                for(int j = 0; j < ministryInterestTableModel.getColumnCount()-1; j++){
                    interestAttribs[j] = ministryInterestTableModel.getValueAt(index, j);
                }
                Interest interestObj = new Interest((String)interestAttribs[0],
                                                 (String)interestAttribs[1]);
                //Get the original Interests in the Interests ArrayList at the row index
                //in the interestUpdatedList
                Interest oldInterestObj = interest.get(index);
                updateInterests = dbManager.updateRecord("dinterest",oldInterestObj, interestObj, depKey);
                if(!updateInterests){
                    updateSaveError("a ministry interest");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            //Update Histories
            boolean updateHistories;
            for(int i = 0; i < historyUpdateSize; i++){
                updateHistories = false;
                int index = historyUpdatedList.get(i);
                Object[] historyAttribs = new Object[ministryHistoryTableModel.getColumnCount()-1];
                for(int j = 0; j < ministryHistoryTableModel.getColumnCount()-1; j++){
                    historyAttribs[j] = ministryHistoryTableModel.getValueAt(index, j);
                }
                History historyObj = new History((String)historyAttribs[0],
                                                 (String)historyAttribs[1],
                                                 (String)historyAttribs[2]);
                //Get the original History in the histories ArrayList at the row index
                //in the historyUpdatedList
                History oldHistoryObj = history.get(index);
                updateHistories = dbManager.updateRecord("dhistory",oldHistoryObj, historyObj, depKey);
                if(!updateHistories){
                    updateSaveError("a ministry history");
                    //dbManager.commitAll();
                    return;
                }//if
            }//for

            ///////////////////////////////////////////////////////////////////
            //Save Successful
            ///////////////////////////////////////////////////////////////////
            boolean saveSuccessful = dbManager.commitAll();
            if(saveSuccessful){
                JOptionPane.showMessageDialog(null,"Save successful!", "Save",
                    JOptionPane.INFORMATION_MESSAGE);
                this.dispose();//close window
            }//if
            else{
                JOptionPane.showMessageDialog(null, "Sorry, the save was not successful due to an error" + "\n"
                        + "Please contact your Database Administrator, a.k.a Thomas Naps, for help if this persists.",
                        "Database Saving Error", JOptionPane.ERROR_MESSAGE);
            }//else
        }//try
        catch(Exception ex){
            JOptionPane.showMessageDialog(null, "Sorry, the save cannot continue due to an error" + "\n" +
                    "Please contact your Database Administrator, a.k.a Thomas Naps, for help if this persists."
                    + "\n" + "EditHouseholdGui.java: save() Method.",
                    "Database Saving Error", JOptionPane.ERROR_MESSAGE);
            ex.getMessage();
            ex.printStackTrace();
        }//catch
    }//save()

    /**
     * Initializes fields to the editing record
     * @param String[] adultArray - array of the adult key to edit.
     */
    private void initFields(String[] depArray)
    {
        try{
            DBManager dbManager = new DBManager();
            int deletedCol;//used to keep track of the index of the "Deleted" column

            //Set Dependent Size - Always only 1 dependent
            depSize = 1;

            //Set Dependent Key
            depKey[0] = depArray[0];
            depKey[1] = depArray[1];
            depKey[2] = depArray[2];

            //Get Ministry Names
            ministryNames = dbManager.getMinistryNames(true);
            String[] ministryNamesArray = new String[ministryNames.size()+1];

            //copy ministry names into string array
            ministryNamesArray[0] = "";
            for(int m = 0; m < ministryNames.size(); m++){
                ministryNamesArray[m+1] = ministryNames.get(m);
            }//for

            //Set "Ministry Name" column to be a drop-down of Ministry Names
            setComboBoxRenderer(jMinistryInterestTable, ministryNamesArray);
            setComboBoxRenderer(jMinistryHistoryTable, ministryNamesArray);

            //Set "Religeous Schooling" column
            String[] school = {"","Religious School", "Day School", "Other"};
            TableColumn colSchool = jDependentTable.getColumnModel().getColumn(4);
            colSchool.setCellEditor(new MyComboBoxEditor(school));
            colSchool.setCellRenderer(new MyComboBoxRenderer(school));
            jDependentTable.setRowHeight(20);

            //set "Deleted Column Width for each tab
            setDeletedCellWidth(jDependentTable,50);
            setDeletedCellWidth(jMinistryInterestTable,50);
            setDeletedCellWidth(jMinistryHistoryTable,50);

            //set each table not to have movable columns
            dontMoveColumns(jDependentTable);
            dontMoveColumns(jMinistryInterestTable);
            dontMoveColumns(jMinistryHistoryTable);

            ////////////////////////////////////////////////////////////////////
            /*Get Selected Dependent*/
            ////////////////////////////////////////////////////////////////////
            individual = (Dependent)dbManager.getIndividual(depKey[0], depKey[1], depKey[2]);
            originalIndividualInfoArray = (String[])individual.getAttributes();

            /*Set Dependent Tab Fields*/
            for(int i = 0; i < dependentTableModel.getColumnCount()-1; i++){
                if(originalIndividualInfoArray[i] != null){
                    dependentTableModel.setValueAt(originalIndividualInfoArray[i], 0, i);
                }//if
            }//for-i
            //set Value of "Deleted" cell
            deletedCol = jDependentTable.getColumnCount()-1;
            dependentTableModel.setValueAt((Boolean)false, 0, deletedCol);



            ////////////////////////////////////////////////////////////////////
            /*Get Ministry Interests*/
            ////////////////////////////////////////////////////////////////////
            interest = dbManager.getInterests("dependents", depKey);
            interestSize = getSize(interest);
            ministryInterestTableModel.setRowCount(interestSize);
            jMinistryInterestTable.setRowHeight(20);

            Object[] interestAttribs;
            for(int j = 0; j < interestSize; j++){
                interestAttribs = interest.get(j).getAttributes();
                for(int m = 0; m < interestAttribs.length; m++){
                    if(interestAttribs[m] != null){
                        ministryInterestTableModel.setValueAt(interestAttribs[m], j, m);
                    }//if
                }//for-m
            }//for-j

            //set Value of "Deleted" cell
            deletedCol = jMinistryInterestTable.getColumnCount()-1;
            for(int i = 0; i < interestSize; i++){
                ministryInterestTableModel.setValueAt(false, i, deletedCol);
            }//for

            ////////////////////////////////////////////////////////////////////
            /*Get Ministry Histories*/
            ////////////////////////////////////////////////////////////////////
            history = dbManager.getHistories("dependents", depKey);
            historySize = getSize(history);
            ministryHistoryTableModel.setRowCount(historySize);
            jMinistryHistoryTable.setRowHeight(20);

            Object[] historyAttribs;
            for(int j = 0; j < historySize; j++){
                historyAttribs = history.get(j).getAttributes();
                for(int m = 0; m < historyAttribs.length; m++){
                    if(historyAttribs[m] != null){
                        ministryHistoryTableModel.setValueAt(historyAttribs[m], j, m);
                    }//if
                }//for-m
            }//for-j

            //set Value of "Deleted" cell
            deletedCol = jMinistryHistoryTable.getColumnCount()-1;
            for(int i = 0; i < historySize; i++){
                ministryHistoryTableModel.setValueAt(false, i, deletedCol);
            }//for

        }//try
        catch(Exception ex){
            ex.printStackTrace();
            JOptionPane.showMessageDialog(null, "Error with St Patrick database." + "\n" +
                    "Please contact your Database Administrator, a.k.a Thomas Naps, for help."
                    + "\n" + "(EditAdult.java: initFields() Method)",
                    "Database Error", JOptionPane.ERROR_MESSAGE);
        }//catch

    }//initFields

    /**
     * Initialize arraylists for add update and delete transactions for each
     * tab in the edithousehold gui
     * Initializes in constructor
     */
    private void initArrayLists(){
         /**Initialize UpdatedList for each tab to include original data**/
        //Adults
        for(int i = 0; i < depSize; i++){
            depUpdatedList.add(i);
        }//for

        //Interests
        for(int i = 0; i < interestSize; i++){
            interestUpdatedList.add(i);
        }//for

        //History
        for(int i = 0; i < historySize; i++){
            historyUpdatedList.add(i);
        }//for

    }//initArrayList()

   /**
     * A method to stop cell editing of a JTable
    * @param table - JTable that you want to stop the cell editing
     **/
    private void stopCellEditing(JTable table){
        if (table.getCellEditor() != null) {
            table.getCellEditor().stopCellEditing();
        }//if
    }//stopCellEditing

    /**
    * Method to make the columns in each tab non-re-sizable
    * @param table - table associated with each tab that will have non-re-sizable columns
    */
   private void dontMoveColumns(JTable table){
       //set Main Table to not be able to move columns
        JTableHeader header = table.getTableHeader();
        header.setReorderingAllowed(false);
   }//DontMoveColumns(JTable)

   /**
     * Set the "Deleted" cell to a max width on tabs that
     * have the column
     * @param table - JTable that has this column
     * @param width - The max width of the column
     */
    private void setDeletedCellWidth(JTable table,int width){
        table.getColumnModel().getColumn(table.getColumnCount()-1).setMaxWidth(width);
    }

   /**
     * Set a combo box renderer for tables with Combo Box Cells
     * @param table - table with cells that need a combo box
     * @param array - array of items you would like to put in the combo box
     */
    private void setComboBoxRenderer(JTable table, String[] array){
        //set "Ministry Name" column of Ministry Tab to be
        //a drop-down of all ministries
        int colCount = table.getColumnCount();
        TableColumn colHistory = table.getColumnModel().getColumn(0);
        colHistory.setCellEditor(new MyComboBoxEditor(array));
        colHistory.setCellRenderer(new MyComboBoxRenderer(array));
        table.setRowHeight(20);

        //set other columns that are not combo boxes
        for(int i = 1; i<colCount-1; i++){
            TableColumn otherCols = table.getColumnModel().getColumn(i);
            otherCols.setCellRenderer(new CellRenderer());
        }//for

    }//setComboBox Renderer

   /**
     * Set a cell renderer to change color when a row is marked delete
     * @param table - table with delete options
     */
    private void setCellRenderer(JTable table, int columnIndex){
        //for(int i = 0; i < table.getColumnCount(); i++){
            TableColumn col = table.getColumnModel().getColumn(columnIndex);
            col.setCellRenderer(new CellRenderer());
        //}//for
    }//setCellRenderer(JTable)

   /**
     * Gets the size of the arraylist so that it is not null if the
     * the arraylist is empty
     * @param arrayList - the arraylist needing a size.
     * @return int - returns 0 if it is empty, 1,2,.. if it is not empty.
     */
    private int getSize(ArrayList arrayList){
        int size;
        if(arrayList.isEmpty()){
            size = 0;
        }//if
        else{
            size = arrayList.size();
        }//else
        return size;
    }//getSize()

     /**
     * Save error message for deleting objects from the database
     * @param classification - string either "adult", "dependent","ministry interest",
     * "contribution", "ministry history", or "address"
     */
    private void deleteSaveError(String classification){
        if(classification.equals("family")){
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "deleting this " + classification + "record"
                            + " from the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists.",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
        }else{
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "deleting a " + classification + "record"
                            + " from the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists.",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
        }//else
    }

    /**
     * Save error message for added objects from the database
     * @param classification - string either "adult", "dependent","ministry interest",
     * "contribution", "ministry history", or "address"
     */
    private void addSaveError(String classification){
        if(classification.equals("family")){
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "adding this " + classification + "record"
                            + " to the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists.",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
        }else{
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "adding " + classification + " record"
                            + " to the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists.",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
        }//else
    }

    /**
     * Save error message for updated objects from the database
     * @param classification - string either "adult", "dependent","ministry interest",
     * "contribution", "ministry history", or "address"
     */
    private void updateSaveError(String classification){
        if(classification.equals("family")){
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "updating this " + classification + "record"
                            + " to the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists.",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
        }else{
            JOptionPane.showMessageDialog(null, "Sorry, there was an error "
                + "updating " + classification + " record"
                            + " to the database." +"\n"+
                            "Please contact your Database Administrator,"
                            + " a.k.a Thomas Naps, for help if this persists.",
                            "Database Save Error", JOptionPane.ERROR_MESSAGE);
        }//else
    }


    /**
     * Method to Verify all Phone fields are in correct format
     */
    private String verifyPhoneFields(){
        int depCount = 0;
        String phones = "";

        //Adult Tab
        for(int i = 0; i < dependentTableModel.getRowCount(); i++){
            String phone1 = (String)dependentTableModel.getValueAt(i, 5);
            //if phones are empty and the row is not deleted
            if(!phone1.equals("") && phone1.length()!=13){
                    depCount ++;
            }//if
        }//for

        if(depCount != 0){
            phones = phones + "\n" + "Dependent Tab";
        }//if

        return phones;

    }//verifyPhoneFields();

    /**
     * Method to Verify all date fields are in correct format
     *
     * @return String of Tabs that do not have proper
     * date format
     */
    private String verifyDateFields(){
        int depCount = 0;
        int historyCount = 0;
        String dates = "";

        //Adult Tab
        for(int i = 0; i < dependentTableModel.getRowCount(); i++){
            //Field is required, don't allow empty string.
            if(!Validator.isDate((String)dependentTableModel.getValueAt(i, 2))
                    && !(dependentTableModel.getValueAt(i, 2).toString().trim()).equals("")){
                depCount++;
            }//if
        }//for

        //Ministry History
        //if ministry history rows exist
        if(ministryHistoryTableModel.getRowCount() > 0){
            for(int i = 0; i < ministryHistoryTableModel.getRowCount(); i++){
                //Check each row for column 1,2,3 (primary keys)
                if(!Validator.isDate(((String)ministryHistoryTableModel.getValueAt(i,1)))
                        && !((String)ministryHistoryTableModel.getValueAt(i,1)).equals("")
                        && !(Boolean)ministryHistoryTableModel.getValueAt(i, ministryHistoryTableModel.getColumnCount()-1))
                {
                    historyCount ++;
                }//if
            }//for
        }//if-rowcount

        if(depCount != 0){
            dates = dates + "\n" + "Dependent Tab";
        }//if
        if(historyCount != 0){
            dates = dates + "\n" + "Ministry History Tab";
        }//if

        return dates;

    }//verifyDateFields();

   /**
    * Check for duplicates within each tab
    * @return boolean false if there are duplicates; true if there is no duplicates
    * @param TableModel tableModel is the table model of the tab you want to check duplicates of
    * @param Int primaryKey is the size of the primary key of the table
    */
    private boolean checkDups(DefaultTableModel tableModel, int primaryKey){
        int rowCount = tableModel.getRowCount();

        boolean noDuplicates = true;

        Outer:
        for(int i = 0; i < rowCount; i++){
            int equalColumnCount = 0;

            //check first three columns
            for(int k = 0; k <= rowCount && k != i; k++){
                for(int j = 0; j < primaryKey; j++){
                    if(tableModel.getValueAt(i, j).equals(tableModel.getValueAt(k, j))
                            && ((Boolean)tableModel.getValueAt(i, tableModel.getColumnCount()-1) == false)
                            && ((Boolean)tableModel.getValueAt(k, tableModel.getColumnCount()-1) == false))
                    {
                        equalColumnCount++;
                    }//if
                }//for-j

                if(equalColumnCount == primaryKey){
                    noDuplicates = false;
                    break Outer;
                }//if
                equalColumnCount = 0;
            }//for-k
        }//for-i
        return noDuplicates;
    }//checkDups

    /**
     * Method to verify no duplicate rows among the different tabs
     * @return String of Tabs that have duplicate rows
     */
    private String verifyDuplicateRows(){
        //do not need to check duplicates in family because
        //you can only add one row.
        boolean depDups = checkDups(dependentTableModel,3);
        boolean interestDups = checkDups(ministryInterestTableModel,1);//ministry date is the primary key
        boolean historyDups = checkDups(ministryHistoryTableModel,2);

        String dupTabs = "";

        if(depDups && interestDups && historyDups){
            //do nothing
        }//if
        else{
            if(!depDups){
                dupTabs = dupTabs + "\n" + "Dependent Tab:"
                        + " Unique fields are the First Name, "
                        + "Last Name, and Date of Birth.";
            }//if
            if(!interestDups){
                dupTabs = dupTabs + "\n" + "Ministry Interest Tab:"
                        + " Unique fields is the Ministry Name.";
            }//if
            if(!historyDups){
                dupTabs = dupTabs + "\n" + "Ministry History Tab:"
                        + " Unique fields are the Ministry Name and Date.";
            }//if
        }//else

        return dupTabs;
    }

    /**
     * Method to verify all required fields are complete
     *
     * @return String of Tabs that do not have completed required fields
     */
    private String verifyRequiredFields(){
        //Check Required fields of each tab then clear for another entry
        boolean depSave = checkDepTab();
        boolean ministryInterestSave = checkInterestTab();
        boolean ministryHistorySave = checkHistoryTab();

        String nullTabs = "";

        if(depSave && ministryInterestSave && ministryHistorySave)
        {
            //do nothing
        }//if
        else{
            if(!depSave){
                nullTabs = nullTabs + "\n" + "Dependent Tab";
            }//if
            if(!ministryInterestSave){
                nullTabs = nullTabs + "\n" + "Ministry Interest Tab";
            }//if
            if(!ministryHistorySave){
                nullTabs = nullTabs + "\n" + "Ministry History Tab";
            }//if
        }//else
        return nullTabs;
    }//verifyRequiredFields

    /**
     * Checks the Dependent Tab if all
     * required fields are complete
     */
    private boolean checkDepTab(){
        boolean adultSave = false;
        int nullCount = 0;
        //check adult
        for(int i = 0; i < dependentTableModel.getRowCount(); i++){
            //Check each row for column 1,2,3 (primary keys)
            if(dependentTableModel.getValueAt(i,0).equals("")
                    | dependentTableModel.getValueAt(i,1).equals("")
                    | dependentTableModel.getValueAt(i,2).equals("")
                    && !(Boolean)dependentTableModel.getValueAt(i, dependentTableModel.getColumnCount()-1))
            {
                nullCount ++;
            }//if
        }//for

        if(nullCount != 0){
            adultSave = false;
        }//if
        else{
            adultSave = true;
        }//else
        return adultSave;

    }//checkDepTab()

    /**
     * Checks the Interest Tab if all
     * required fields are complete
     */
    private boolean checkInterestTab(){
        boolean interestSave = false;
        int nullCount = 0;
        //check Interest, if rows exist
        if(ministryInterestTableModel.getRowCount() > 0){
            for(int i = 0; i < ministryInterestTableModel.getRowCount(); i++){
                //Check each row for required fields
                if(ministryInterestTableModel.getValueAt(i,0).equals("")
                        && !(Boolean)ministryInterestTableModel.getValueAt(i, ministryInterestTableModel.getColumnCount()-1))
                {
                    nullCount ++;
                }//if
            }//for
        }//if

        if(nullCount != 0){
            interestSave = false;
        }//if
        else{
            interestSave = true;
        }//else
        return interestSave;
    }//checkInterestTab()

    /**
     * Checks the History Tab if all
     * required fields are complete
     */
    private boolean checkHistoryTab(){
        boolean historySave = false;
        int nullCount = 0;
        //check Money, if rows exist
        if(ministryHistoryTableModel.getRowCount() > 0){
            for(int i = 0; i < ministryHistoryTableModel.getRowCount(); i++){
                //Check each row for required fields
                if(ministryHistoryTableModel.getValueAt(i,0).equals("")
                        |ministryHistoryTableModel.getValueAt(i,1).equals("")
                        && !(Boolean)ministryHistoryTableModel.getValueAt(i, ministryHistoryTableModel.getColumnCount()-1))
                {
                    nullCount ++;
                }//if
            }//for
        }//if

        if(nullCount != 0){
            historySave = false;
        }//if
        else{
            historySave = true;
        }//else
        return historySave;
    }//checkHistoryTab()

    /**
    * Opens Edit Adult Window
    */
    public static void run(String[] depArray)
    {
        new EditDependent(depArray).setVisible(true);
    }//run

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btAddRow;
    private javax.swing.JButton btCancel;
    private javax.swing.JButton btRemoveRow;
    private javax.swing.JButton btSave;
    private javax.swing.JTable jDependentTable;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JTable jMinistryHistoryTable;
    private javax.swing.JTable jMinistryInterestTable;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JLabel lblAddNewHousehold;
    private javax.swing.JTabbedPane tabbedPane;
    // End of variables declaration//GEN-END:variables

        private EditIndividualTableModel dependentTableModel = new EditIndividualTableModel(
                                    new Object [][] {
                                        {"","","","","","","",false}
                                    },
                                    new String [] {
                                        "First Name*", "Last Name*", "Birthdate*",
                                        "School", "Religious Schooling",
                                        "Personal Phone","Notes","Deleted"
                                    }
                                );
    private TableModel ministryInterestTableModel = new TableModel(
                            new Object [][] {
                                {"","",false}
                            },
                            new String [] {
                                "Ministry Name*", "Availability","Deleted"});

    private TableModel ministryHistoryTableModel = new TableModel(
                                    new Object [][] {
                                        {"","","",false}
                                    },
                                    new String [] {
                                        "Ministry Name*", "Date*","Primary Position","Deleted"});
}
